package cc.magicjson.tools.chain.example;


import cc.magicjson.tools.chain.domain.Order;
import cc.magicjson.tools.chain.processor.condition.ConditionProcessor;

/**
 * 支付优惠场景示例
 * 展示如何使用ConditionProcessor处理积分和优惠券的折扣计算，并支持回滚和回调功能
 */
public class PaymentDiscountExample {

    // 积分抵扣比例：100积分抵1元
    private static final double POINTS_RATIO = 100.0;

    // 满减券规则：满50元减1元
    private static final double COUPON_THRESHOLD = 50.0;
    private static final double COUPON_DISCOUNT = 1.0;

    public static void main(String[] args) {
        // 创建初始订单，金额为120元，VIP用户
        Order initialOrder = Order.createInitial(120.0, true);
        System.out.println("初始订单: " + initialOrder);

        // 创建条件处理器
        ConditionProcessor<Order> processor = createProcessor();

        // 正常处理订单
        Order processedOrder = processor.process(initialOrder);
        System.out.println("处理后订单: " + processedOrder);

        // 测试异常情况的回滚
        testRollback();

        // 测试异步处理
        testAsyncProcessing();
    }

    /**
     * 创建支付优惠处理器
     */
    private static ConditionProcessor<Order> createProcessor() {
        // 定义积分和优惠券的处理链
        ConditionProcessor.ConditionChain<Order> pointsChain = ConditionProcessor.ConditionChain.<Order>of()
            .priority(10)  // 设置高优先级，先处理积分
            .whenMatchWithRollback(
                // 条件：未支付且订单金额大于0
                order -> !order.isPaid() && order.amount() > 0,
                // 正向操作：应用积分折扣
                order -> {
                    // 假设用户可用积分为500，计算可抵扣金额
                    double availablePoints = 500;
                    double discountValue = availablePoints / POINTS_RATIO;

                    // 更新订单
                    System.out.println("应用积分折扣: " + discountValue + "元 (使用" + availablePoints + "积分)");
                    return order.withPoints(availablePoints, discountValue);
                },
                // 回滚操作：取消积分折扣
                order -> {
                    System.out.println("回滚积分折扣");
                    return order.resetDiscount();
                }

            );

        ConditionProcessor.ConditionChain<Order> couponChain = ConditionProcessor.ConditionChain.<Order>of()
            .priority(5)  // 设置较低优先级，在积分之后处理优惠券
            .whenMatchWithRollback(
                // 条件：未支付且订单金额大于优惠券阈值
                order -> !order.isPaid() && order.amount() >= COUPON_THRESHOLD,
                // 正向操作：应用优惠券折扣
                order -> {
                    // 计算优惠券数量，每满50元使用一张优惠券
                    int couponCount = (int) (order.amount() / COUPON_THRESHOLD);
                    double discountValue = couponCount * COUPON_DISCOUNT;

                    // 更新订单
                    System.out.println("应用优惠券折扣: " + discountValue + "元 (使用" + couponCount + "张优惠券)");
                    return order.withCoupons(couponCount, discountValue);
                },
                // 回滚操作：取消优惠券折扣
                order -> {
                    System.out.println("回滚优惠券折扣");
                    return order.resetDiscount();
                }
            );

        // 创建处理器并配置回调和异常处理
        return ConditionProcessor.<Order>builder()
            .enablePriority(true)  // 启用优先级
            .enableRollback(true)  // 启用回滚功能
            .addChain(pointsChain)
            .addChain(couponChain)
            .defaultHandler(order -> System.out.println("没有任何优惠条件匹配"))
            .exceptionHandler((order, ex) -> System.err.println("处理订单发生异常: " + ex.getMessage()))
            .onSuccess(order -> System.out.println("订单处理成功! 最终金额: " + order.finalAmount() + "元"))
            .onFailure((order, ex) -> System.err.println("订单处理失败: " + ex.getMessage()))
            .build();
    }

    /**
     * 测试异常情况下的回滚功能
     */
    private static void testRollback() {
        System.out.println("\n===测试回滚功能===");
        Order initialOrder = Order.createInitial(200.0, true);
        System.out.println("初始订单: " + initialOrder);

        // 创建处理器但添加一个会抛出异常的处理器
        ConditionProcessor<Order> processor = createProcessor();
        processor.addCondition(1,
            order -> true,  // 条件总是匹配
            order -> {
                // 先应用一些优惠
                Order updatedOrder = order.withPoints(300, 3.0);
                System.out.println("应用了一些优惠后: " + updatedOrder);

                // 然后抛出异常
                throw new RuntimeException("支付系统异常，需要回滚！");
            },
            order -> {
                System.out.println("执行额外处理器的回滚");
                return order;
            },
            true  // 匹配后停止
        );

        try {
            Order result = processor.process(initialOrder);
            System.out.println("处理结果: " + result);
        } catch (Exception e) {
            System.out.println("捕获到异常: " + e.getMessage());
        }
    }

    /**
     * 测试异步处理功能
     */
    private static void testAsyncProcessing() {
        System.out.println("\n===测试异步处理===");
        Order initialOrder = Order.createInitial(150.0, false);
        System.out.println("初始订单: " + initialOrder);

        ConditionProcessor<Order> processor = createProcessor();

        processor.processAsync(initialOrder)
            .thenAccept(order -> System.out.println("异步处理完成，最终订单: " + order))
            .exceptionally(ex -> {
                System.err.println("异步处理发生异常: " + ex.getMessage());
                return null;
            });

        // 为了在示例中看到异步结果，等待一下
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
